
#include <nkipc.h>
#include <nkevent.h>


int __nk_ipc_mid__ = -1;
int __nk_ipc_fd__ = -1;

void (*nk_ipc_uni_cb[NK_IPC_MOD_NUM])(void *rmsg, int len, void **smsg, int *slen );
void (*nk_ipc_mul_cb[NK_IPC_MSG_TYPE_NUM - TIPC_RESERVED_TYPES])(void *msg, int len);

static void nk_ipc_read(int fd, short event, void *arg)
{
#if 0
	struct nk_ipc_head head;
	int len;
	int tlen = 0;
	int dlen;
	char *buf;
	int type;
	int sender;
	void (*func)(void *msg, int len) = NULL;

	do {
		len = read(fd, &head + tlen, sizeof(head) - tlen);
		tlen += len;
	} while (tlen < sizeof(head));

	type = nk_ipc_get_type(&head);
	sender = nk_ipc_get_sender(&head);

	if (type == NK_IPC_MSG_TYPE_UNI) {
	} else {
		if (nk_ipc_mul_cb[type]) {
			func = nk_ipc_mul_cb[type];
		}
	}

	dlen = nk_ipc_get_len(&head);
	buf = malloc(dlen);
	if (!buf) {
	}

	tlen = 0;
	do {
		len = read(fd, buf + tlen, dlen - tlen);
		tlen += len;
	} while (tlen < dlen);


#endif
}


int nk_ipc_init(int mid)
{
	int fd;
	int ret;
	struct sockaddr_tipc sa;

	fd = socket(AF_TIPC, SOCK_RDM, 0);

	memset(&sa, 0, sizeof(sa));

#if 1
	sa.family = AF_TIPC;
	sa.addrtype = TIPC_ADDR_NAME;
	sa.addr.name.name.type = NK_IPC_MSG_TYPE_UNI;
	sa.addr.name.name.instance = mid;
	sa.addr.name.domain = 0;
	sa.scope = TIPC_ZONE_SCOPE;
#else
	sa.family = AF_TIPC;
	sa.addrtype = TIPC_ADDR_ID;
	sa.addr.id.ref = 0;
	sa.addr.id.node = tipc_addr(1, 0, mid);
	sa.scope = TIPC_ZONE_SCOPE;
#endif

	ret = bind(fd, (struct sockaddr *)&sa, sizeof(sa));
	if (ret) {
		printf("Bind fd failed\n");
		goto out;
	}

	__nk_ipc_mid__ = mid;
	__nk_ipc_fd__ = fd;

	nk_ev_set(fd, EV_READ | EV_PERSIST, nk_ipc_read, NULL);
out:
	return ret;
}

int nk_ipc_send(int mid, char *buf, int len)
{
	struct sockaddr_tipc sa;

	if (__nk_ipc_fd__ < 0) {
		return -1;
	}

	memset(&sa, 0, sizeof(sa));

#if 1
	sa.family = AF_TIPC;
	sa.addrtype = TIPC_ADDR_NAME;
	sa.addr.name.name.type = NK_IPC_MSG_TYPE_UNI;
	sa.addr.name.name.instance = mid;
	sa.addr.name.domain = 0;
	sa.scope = TIPC_ZONE_SCOPE;
#else
	sa.family = AF_TIPC;
	sa.addrtype = TIPC_ADDR_ID;
	sa.addr.id.ref = 0;
	sa.addr.id.node = tipc_addr(1, 0, mid);
	sa.scope = TIPC_ZONE_SCOPE;
#endif

	sendto(__nk_ipc_fd__, buf, len + 1, 0, (struct sockaddr*)&sa, sizeof(sa));

	return 0;
}


int nk_ipc_recv(char *buf, int len)
{
	socklen_t sa_len;
	struct sockaddr_tipc sa;

	if (__nk_ipc_fd__ < 0) {
		return -1;
	}

	//recv(__nk_ipc_fd__, buf, len, 0);
	recvfrom(__nk_ipc_fd__, buf, len, 0, (struct sockaddr *)&sa, &sa_len);

	printf("peer addrtype %d, id %d, ref %d, " 
			"zone %d, cluster %d, node %d\n",
			sa.addrtype, sa.addr.id.node, sa.addr.id.ref,
			tipc_zone(sa.addr.id.ref),
			tipc_cluster(sa.addr.id.ref),
			tipc_node(sa.addr.id.ref));

	return 0;
}

int nk_ipc_send_and_recv()
{

	return 0;
}

void nk_ipc_sub_msg(int type, void (*cb)(void *msg, int len))
{
	nk_ipc_mul_cb[type] = cb;	
}

void nk_ipc_register(int mid, void (*cb)(void *rmsg, int rlen, void **smsg, int *slen))
{
	nk_ipc_uni_cb[mid] = cb;
}


